<?php
/**
 * 基本的请求处理类
 * 提供从$_POST和$_GET中取数据的能力,同时可以进行XSS过滤.
 * 另外cookie也可以通过本类的实例来获取和设置.
 * 
 * @author Leo Ning 2010-09-03
 */
uses ( 'libs/XssCleaner.inc' );
class BaseRequest implements IRequest {
	private $use_xss_clean = false;
	private $xss_cleaner;
	private $cookie_options;
	private $quotes_gpc;
	public function __construct($xss_clean = false, $cookie_options = array()) {
		$this->use_xss_clean = $xss_clean;
		$this->quotes_gpc = get_magic_quotes_gpc ();
		$this->xss_cleaner = new XssCleaner ();
		$this->cookie_options = array_merge ( array ('cookie_domain' => '', 'cookie_path' => '/', 'cookie_secure' => false, 'cookie_expire' => 0 ), $cookie_options );
		$this->_sanitize_globals ();
	}
	/**
	 * 获取客户端传过来的值无论是通过GET方式还是POST方式
	 * @param string $name 
	 * @param mixed $default
	 * @param boolean $xss_clean 是否进行xss过滤
	 * @return mixed
	 */
	public function get($name, $default = '', $xss_clean = false) {
		$ary = isset ( $_POST [$name] ) ? $_POST : $_GET;
		if (! isset ( $ary [$name] )) {
			return $default;
		}
		if ($xss_clean === true && $this->use_xss_clean === false) {
			return $this->xss_cleaner->xss_clean ( $ary [$name] );
		}
		return $ary [$name];
	}
	/**
	 * 从COOKIE读取数据
	 * @param string $name
	 * @param mixed $default
	 * @param boolean $xss_clean 是否进行xss过滤
	 * @return mixed
	 */
	public function cookie($name, $default = '', $xss_clean = false) {
		$ary = $_COOKIE;
		if (! isset ( $ary [$name] )) {
			return $default;
		}
		if ($xss_clean === true && $this->use_xss_clean === false) {
			return $this->xss_cleaner->xss_clean ( $ary [$name] );
		}
		return $ary [$name];
	}
	/**
	 * 设置COOKIE,当$value=null或$expire小于0时从COOKIE中删除$name.
	 * @param string $name
	 * @param mixed $value
	 * @param int $expire
	 */
	public function setCookie($name, $value = null, $expire = null) {
		extract ( $this->cookie_options );
		$expire = is_numeric ( $expire ) ? $expire : $cookie_expire;
		$expire = is_null ( $value ) ? time () - 36000 : (empty ( $expire ) ? 0 : time () + $expire);
		@setcookie ( $name, $value, $expire, $cookie_path, $cookie_domain, $cookie_secure );
	}
	//处理全局输入
	private function _sanitize_globals() {
		$_GET = $this->_clean_input_data ( $_GET );
		$_POST = $this->_clean_input_data ( $_POST );
		unset ( $_COOKIE ['$Version'] );
		unset ( $_COOKIE ['$Path'] );
		unset ( $_COOKIE ['$Domain'] );
		$_COOKIE = $this->_clean_input_data ( $_COOKIE );
	}
	/**
	 * Clean Input Data
	 *
	 * This is a helper function. It escapes data and
	 * standardizes newline characters to \n
	 *
	 * @access	private
	 * @param	string
	 * @return	string
	 */
	private function _clean_input_data($str) {
		if (is_array ( $str )) {
			$new_array = array ();
			foreach ( $str as $key => $val ) {
				$new_array [$this->_clean_input_keys ( $key )] = $this->_clean_input_data ( $val );
			}
			return $new_array;
		}
		
		// We strip slashes if magic quotes is on to keep things consistent
		if ($this->quotes_gpc) {
			$str = stripslashes ( $str );
		}
		
		// Should we filter the input data?
		if ($this->use_xss_clean === true) {
			$str = $this->xss_cleaner->xss_clean ( $str );
		}
		
		// Standardize newlines
		if (strpos ( $str, "\r" ) !== FALSE) {
			$str = str_replace ( array ("\r\n", "\r" ), "\n", $str );
		}
		
		return $str;
	}
	/**
	 * Clean Keys
	 *
	 * This is a helper function. To prevent malicious users
	 * from trying to exploit keys we make sure that keys are
	 * only named with alpha-numeric text and a few other items.
	 *
	 * @access	private
	 * @param	string
	 * @return	string
	 */
	private function _clean_input_keys($str) {
		if (! preg_match ( "/^[a-z0-9:_\/-]+$/i", $str )) {
			exit ( 'Disallowed Key Characters.' );
		}
		return $str;
	}
}